import { IvcsError } from '../base/error';
import { CCSClient, validateCcsClient,dealWithCcsSendMessageResponse } from './ccs_client';
import { stopStream } from './irtcScript';

/**
 * im通话升降级成语音/视频通话，管理类
 */
class ImUpgradeMedia {
	constructor() {
		this.fromClientId = ''; // 发起请求者clientId
		this.media = 'audio'; // 发起请求的媒体类型
	}

	/**
	 * 请求升级
	 * @param {string} media "media": "video"/ "audio",
	 * @param {string} toWhom 发送给谁 clientId具体的用户 'customers'= 访客;'agents'= 坐席;'others'= 除了自己的所有人; 'all' = 所有人;
	 * @param {function} onSuccess
	 * @param {function} onFailure
	 * @param {CCSClient} ccsClient
	 */
	async requestUpgrade(media, toWhom, onSuccess, onFailure, ccsClient) {
		let isValid = validateCcsClient(ccsClient);
		if (isValid != 'ok') {
			onFailure(isValid);
		}
		const createStream = function (media) {
			return new Promise((resolve, reject) => {
				let stream;
				let constraints;
				if (media === 'audio') {
					// 预创建语音流
					constraints = { audio: true };
				} else if (media === 'video') {
					constraints = { audio: true, video: true };
				}
				navigator.mediaDevices
					.getUserMedia(constraints)
					.then(mediaStream => {
						stream = mediaStream;
						stopStream(stream);
						resolve(stream);
					})
					.catch(err => {
						stopStream(stream);
						console.log('accept im-upgrade-createStream error' + err.name + ': ' + err.message);
						// this.reject(media,err.name || err.message || err,()=>{},()=>{});
						reject(new IvcsError('60000', err.name || err.message || err));
					});
			});
		};
		try {
			await createStream(media);
			const data = { media };
			this.media = media;
			this.fromClientId = toWhom;
			ccsClient.sendMessage('request-upgrade', data, toWhom,  (status, resp)=> {
				if (status === 'ok') {
					onSuccess(resp);
				} else {
                    dealWithCcsSendMessageResponse(status,resp,onFailure);
				}
			});
		} catch (error) {
            console.log('ivcs-js-sdk-requestUpgrade error',error);
			onFailure(error);
		}
	}

	/**
	 * 接受对方的升级请求
	 * @param {string} media "media": "video"/ "audio",
	 * @param {function} onSuccess
	 * @param {function} onFailure {code:'60000',message:AbortError［中止错误］;NotAllowedError［拒绝错误］;NotFoundError［找不到错误］;NotReadableError［无法读取错误］;OverconstrainedError［无法满足要求错误］;SecurityError［安全错误］}
	 * @param {CCSClient} ccsClient
	 */
	async accept(media, onSuccess, onFailure, ccsClient) {
		let isValid = validateCcsClient(ccsClient);
		if (isValid != 'ok') {
			onFailure(isValid);
		}
		const createStream = function (media) {
			return new Promise((resolve, reject) => {
				let stream;
				let constraints;
				if (media === 'audio') {
					// 预创建语音流
					constraints = { audio: true };
				} else if (media === 'video') {
					constraints = { audio: true, video: true };
				}
				navigator.mediaDevices
					.getUserMedia(constraints)
					.then(mediaStream => {
						stream = mediaStream;
						stopStream(stream);
						resolve(stream);
					})
					.catch(err => {
						stopStream(stream);
						console.log('accept im-upgrade-createStream error' + err.name + ': ' + err.message);
						// this.reject(media,err.name || err.message || err,()=>{},()=>{});
						reject(new IvcsError('60000', err.name || err.message || err));
					});
			});
		};
		try {
			await createStream(media);
			const data = { media };
			const toWhom = this.fromClientId ? this.fromClientId : 'others';
			ccsClient.sendMessage('accept-upgrade', data, toWhom, (status, resp) => {
				if (status === 'ok') {
					onSuccess(resp);
				} else {
                    dealWithCcsSendMessageResponse(status,resp,onFailure);
				}
			});
		} catch (error) {
            console.log('ivcs-js-sdk-acceptUpgrade error',error);
			onFailure(error);
		}
	}

	/**
	 * 拒绝接听
	 * @param {string} media "media": "video"/ "audio",
	 * @param {object} reason {code,message}
	 * @param {function} onSuccess
	 * @param {function} onFailure
	 * @param {CCSClient} ccsClient
	 */
	reject(media, reason, onSuccess, onFailure, ccsClient) {
		let isValid = validateCcsClient(ccsClient);
		if (isValid != 'ok') {
			onFailure(isValid);
		}
		const data = { media, reason };
		const toWhom = this.fromClientId ? this.fromClientId : 'others';
		ccsClient.sendMessage('reject-upgrade', data, toWhom, (status, resp) => {
			if (status === 'ok') {
				onSuccess(resp);
			} else {
                dealWithCcsSendMessageResponse(status,resp,onFailure);
			}
		});
	}

	/**
	 * 取消请求升级
	 * @param {string} reason 默认‘normal’
	 * @param {function} onSuccess
	 * @param {function} onFailure
	 * @param {CCSClient} ccsClient
	 */
	cancel(reason = 'normal', onSuccess, onFailure, ccsClient) {
		let isValid = validateCcsClient(ccsClient);
		if (isValid != 'ok') {
			onFailure(isValid);
		}
		const data = { reason, media: this.media };
		const toWhom = this.fromClientId ? this.fromClientId : 'others';
		ccsClient.sendMessage('cancel-upgrade', data, toWhom, (status, resp) => {
			if (status === 'ok') {
				onSuccess(resp);
			} else {
                dealWithCcsSendMessageResponse(status,resp,onFailure);
			}
		});
	}

	/**
	 * 监听升降级的事件
	 * @param {function} ack {type:'request-upgrade'|'accept-upgrade'|'reject-upgrade'|'cancel-upgrade',from:{},to:{},data:{media,roomId,roomToken,reason}}
	 */
	onUpgrade(ack, ccsClient) {
		let isValid = validateCcsClient(ccsClient);
		if (isValid != 'ok') {
			console.error('onUpgrade error', isValid);
			return;
		}
		ccsClient.onUpgradeAck(data => {
			if (data?.data?.type === 'request-upgrade') {
				this.fromClientId = data?.from;
			}
			ack(data);
		});
	}
}

export { ImUpgradeMedia };
